clear

set seed 100

//use "intermediatedata/lichess.dta" 

use "intermediatedata/lichess`1'.dta"
append using "intermediatedata/lichess`2'.dta"


gen timecontrol_base=timecontrol=="`1'+0"
gen timecontrol_iv=timecontrol=="`2'+0"


drop if strpos(event, "tournament")>0


keep if timecontrol_base | timecontrol_iv 

xtset game turn
bys game (turn): gen prev_move=move[_n-1]


keep if abs(moverelo-opponentelo)<=200

drop if start_eval==.
drop if clock==. | opponentclock==. | eval2==.

//// Create matched pairs between 300+0 and 180+0
// Want to match on turn, pieces on board, engine eval
// Needs to be exact match on turn and pieces on board

//bys mover (timecontrol_iv): drop if timecontrol_iv[_N]!=1


// bys mover (timecontrol_iv): drop if timecontrol_iv[1]!=0

xtile evaltile=start_eval, n(50)
gen rand=runiform()

egen matchgroup=group(mover turn evaltile)
bys matchgroup (timecontrol_iv): drop if timecontrol_iv[1]!=0

bys matchgroup timecontrol (rand): gen groupnum=_n if matchgroup!=.
egen matchvar=group(matchgroup groupnum)

bys matchvar: gen size_match=_N if matchvar!=.
tab size_match

bys matchvar: egen clock300=total(clock*(timecontrol_base))
bys matchvar: egen opponentclock300=total(opponentclock*(timecontrol_base))
bys matchvar: egen moverelo300=total(moverelo*(timecontrol_base))

replace clock=clock300 if size_match>1 & size_match!=. & timecontrol_iv
replace opponentclock=opponentclock300 if size_match>1 & size_match!=. & timecontrol_iv

replace moverelo=moverelo300  if size_match>1 & size_match!=. & timecontrol_iv


/////////////////////////////////////////////////////
//Calculate Win Probs 
/////////////////////////////////////
 

gen result2=1 if result=="1-0" & mod(turn,2)==1
replace result2=1 if result=="0-1" & mod(turn,2)==0
replace result2=0 if result=="1-0" & mod(turn,2)==0
replace result2=0 if result=="0-1" & mod(turn,2)==1
replace result2=.5 if result=="1/2-1/2"

gen mover_eval=eval2 if mod(turn,2)==1 
replace mover_eval=-eval2 if mod(turn,2)==0 

replace mover_eval=2000 if mover_eval>2000
replace mover_eval=-2000 if mover_eval<-2000

//
// xtile eval_percentile=mover_eval if substr(eval,1,1)!="#", n(38)
// replace eval_percentile=eval_percentile+1
// replace eval_percentile=0 if substr(eval,1,2)=="#-" & mod(turn,2)==1 | substr(eval,1,2)=="#+" & mod(turn,2)==0
// replace eval_percentile=41 if substr(eval,1,2)=="#+" & mod(turn,2)==1 | substr(eval,1,2)=="#-" & mod(turn,2)==0
//
xtile elo_percentile=moverelo, n(5)
//
// gen clock_percentile=.
// replace clock_percentile=1 if clock<=`1'/60
// replace clock_percentile=2 if clock>`1'/60 & clock<=`1'/60*2
// replace clock_percentile=3 if clock>`1'/60*2 & clock<=`1'/60*3
// replace clock_percentile=4 if clock>`1'/60*3 & clock<=`1'/60*4
// replace clock_percentile=5 if clock>`1'/60*4 & clock<=`1'/60*6
// replace clock_percentile=6 if clock>`1'/60*6 & clock<=`1'/60*12
// replace clock_percentile=7 if clock>`1'/60*12 & clock<=`1'/60*24
// replace clock_percentile=8 if clock>`1'/60*24 & clock<=`1'/60*36
// replace clock_percentile=9 if clock>`1'/60*36 & clock<=`1'/60*48
// replace clock_percentile=10 if clock>`1'/60*48 & clock<=`1'
//
//
// gen clock_opp_percentile=.
// replace clock_opp_percentile=1 if opponentclock<=`1'/60
// replace clock_opp_percentile=2 if opponentclock>`1'/60 & opponentclock<`1'/60*2
// replace clock_opp_percentile=3 if opponentclock>`1'/60*2 & opponentclock<=`1'/60*3
// replace clock_opp_percentile=4 if opponentclock>`1'/60*3 & opponentclock<=`1'/60*4
// replace clock_opp_percentile=5 if opponentclock>`1'/60*4 & opponentclock<=`1'/60*6
// replace clock_opp_percentile=6 if opponentclock>`1'/60*6 & opponentclock<=`1'/60*12
// replace clock_opp_percentile=7 if opponentclock>`1'/60*12 & opponentclock<=`1'/60*24
// replace clock_opp_percentile=8 if opponentclock>`1'/60*24 & opponentclock<=`1'/60*36
// replace clock_opp_percentile=9 if opponentclock>`1'/60*36 & opponentclock<=`1'/60*48
// replace clock_opp_percentile=10 if opponentclock>`1'/60*48 & opponentclock<=`1'


gen matedummy=substr(eval,1,1)=="#"
gen mover_eval_matedummy=mover_eval*matedummy




local clock_knot1=`1'/30
local clock_knot2=`1'/10
local clock_knot3=`1'/5
local clock_knot4=`1'/2

mkspline opponentclockspline=opponentclock, cubic  knots(`clock_knot1' `clock_knot2' `clock_knot3' `clock_knot4')

mkspline evalspline=mover_eval, cubic knots(-1000 -300 -100  100 300 1000)


mkspline clockspline=clock, cubic  knots(`clock_knot1' `clock_knot2' `clock_knot3' `clock_knot4')


gen winprob=.
gen marginalvalueoftime=.

forvalues counter_elo=1/5{
	lassoregress result2 c.clockspline*##c.opponentclockspline*##c.evalspline*  if elo_percentile==`counter_elo' & ///
						timecontrol_base

	//reg result2 c.clockspline*##c.opponentclockspline*##c.evalspline* if !expanded



	/// This chunk of code predicts the winprobability, and takes a numerical derivative with respect to clock
	gen obs_num=_n
	expand 2 if elo_percentile==`counter_elo', gen(expanded)
	replace clock=clock+.001 if expanded 
	drop clockspline*
	mkspline clockspline=clock, cubic  knots(`clock_knot1' `clock_knot2' `clock_knot3' `clock_knot4')
	predict result2_pred  if elo_percentile==`counter_elo'

	preserve
		keep obs_num result2_pred expanded
		drop if !expanded 
		rename result2_pred result2_pred_plusclock
		tempfile plusclock
		save `plusclock', replace
	restore

	drop if expanded

	merge 1:1 obs_num using `plusclock'
	
	
	summ result2_pred*


	replace marginalvalueoftime=(result2_pred_plusclock-result2_pred)/.001 if elo_percentile==`counter_elo'
	replace winprob=result2_pred  if elo_percentile==`counter_elo'
	
	
	summ winprob, detail
	summ marginalvalueoftime, detail
	drop result2_pred
	drop result2_pred_plusclock
	drop obs_num
	drop expanded
	drop _merge
}
//
// gen winprob=.
// gen marginalvalueoftime=.
//
//
// forvalues counter_elo=1/5{
// 	forvalues counter_clock=1/10{
// 		forvalues counter_clock_opp=1/10{
// 			foreach counter_eval in 0 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 41{
//			
// 				qui summ mover_eval clock opponentclock if  ///
// 					eval_percentile==`counter_eval' & ///
// 					clock_percentile==`counter_clock' & ///
// 					clock_opp_percentile==`counter_clock_opp' & ///
// 					elo_percentile==`counter_elo' & ///
// 					timecontrol_base
//				
// 				local numobs=r(N)
// 				disp "`counter_elo' `counter_clock' `counter_clock_opp' `counter_eval': `numobs'"
//				
// 				if r(N)>=10{
//				
//				
// 					qui reg result2 mover_eval clock opponentclock if ///
// 						abs(eval_percentile-`counter_eval')<=1 & ///
// 						abs(clock_percentile-`counter_clock')<=1 & ///
// 						abs(clock_opp_percentile-`counter_clock_opp')<=1 & ///
// 						elo_percentile==`counter_elo' & ///
// 						timecontrol_base
//				
// 					qui predict expectedvalue if  ///
// 						eval_percentile==`counter_eval' & ///
// 						clock_percentile==`counter_clock' & ///
// 						clock_opp_percentile==`counter_clock_opp'   & ///
// 						elo_percentile==`counter_elo'
//					
//					
// 					qui replace marginalvalueoftime=_b[clock] if  ///
// 						eval_percentile==`counter_eval' & ///
// 						clock_percentile==`counter_clock' & ///
// 						clock_opp_percentile==`counter_clock_opp'   & ///
// 						elo_percentile==`counter_elo'
//					
// 					qui replace winprob=expectedvalue if expectedvalue!=.
// 					qui drop expectedvalue
// 				}
// 			}
// 		}
// 	}
// }
// replace eval_percentile=1 if eval_percentile==0
// replace eval_percentile=40 if eval_percentile==41

// tab size_match
// hist marginalvalueoftime if marginalvalueoftime>-.01 & marginalvalueoftime<.1
// graph rename marg_value_hist, replace
// hist winprob if winprob>-1 & winprob<2
// graph rename winprob_hist, replace




cap label var game "Game"
cap label var event "Event"
cap label var white "White Player"
cap label var whiteelo "White Player's Elo"
cap label var black "Black Player"
cap label var blackelo "Black Player's Elo"
cap label var timecontrol "Time Control"
cap label var result "Result (1-0 is a White win, 0-1 is a Black win, 1/2-1/2 is a draw)"
cap label var turn "Turn Number"
cap label var move "Move (Chess Notation)"
cap label var eval "Computer Evaluation"
cap drop v12
cap label var clock "Time Remaining on Clock"
cap label var timecontrol1 "Initial Amount of time in time control"
cap label var timecontrol2 "Increment in time control"
cap label var timetaken "Time Spent on the move"
cap drop timetaken_trim
cap drop eval_numbers_only
cap label var eval2 "Stockfish Evaluation"
cap label var start_clock "Time Remaining on Clock before the move"
cap label var start_eval "Computer Evaluation Before the move"
cap label var whitewin "Dummy for White Winning"
cap label var opponentclock "Opponent's Time Remaining"
cap label var whiteclock "White's Time Remaining"
cap label var blackclock "Black's Time Remaining"
cap label var mover "Player that is moving"
cap label var moverelo "Elo of player that is moving"
cap label var opponent "Player's opponent"
cap label var opponentelo "Elo of opposing player"
cap label var piecetaken "Dummy for Whether a Piece is Captured"
cap label var piecesonboard "Number of Pieces on the Board"
cap label var movercode "Numerical Code to Index Movers"
cap label var opponentcode "Numerical Code to Index Opponents"
cap label var meanelo "Average Elo of the moving player, throughout the dataset"
cap label var timecontrol_base "Dummy variable for the observation corresponding to the time control of interest"
cap label var timecontrol_iv "Dummy Variable for the observation corresponding to the time control for matching"
cap label var prev_move "Notation of the previous move"
cap label var evaltile "Quantile of the Computer Evaluation at the start of the move"
cap label var rand "Random Number, helpful for sorting"
cap label var matchgroup "Variable for the matching procedure, combines mover, turn, and evaluation quantile"
cap label var groupnum "Index within matchgroup and time control"
cap label var matchvar "Index that is unique for each matched pair"
cap label var size_match "1 if unmatched, 2 if matched"
cap label var clock300 "Clock in the baseline time control for each matched pair"
cap label var opponentclock300 "Clock in the baseline time control for each matched pair"
cap label var moverelo300 "Elo in the baseline time control for each matched pair"
cap label var result2 "1 if mover wins, 1/2 if mover draws, 0 if mover loses"
cap label var mover_eval "Evaluation from perspective of mover"
cap label var eval_percentile "Quantiles of Starting Evaluation"
cap label var elo_percentile "Quantiles of Elo"
cap label var clock_percentile "Quantiles of clock"
cap label var clock_opp_percentile "Quantiles of opponent's clock"
cap drop matedummy
cap drop mover_eval_matedummy
cap label var winprob "Win Probability"
cap label var marginalvalueoftime "Marginal Value of 1 second"

//keep if size_match==2
save "cleandata\winprob_matched_dataset`1'_`2'_lassospline.dta", replace
// use "winprob_matched_dataset`1'_`2'", clear
//
// keep if size_match>1 & size_match!=.
//
// xtile turnbin=turn, n(5)
// //gen pos_marginalvalueoftime=marginalvalueoftime //max(0,marginalvalueoftime)
// bys turnbin: egen average_marginal_value=mean(marginalvalueoftime)
//
// tempfile results
// forvalues t=1/5{
// 	ivreghdfe winprob (timetaken=timecontrol_iv) if turnbin==`t', absorb(matchvar)
//	
// 	preserve
// 	parmest, fast
// 	gen turnbin=`t'
// 	drop if parm=="_cons"
// 	cap append using `results'
// 	save `results', replace
// 	restore
// }
// merge m:1 turnbin using `results', nogen
//
// bys turnbin: gen toplot=_n==1 
// bys turnbin: egen mean_turn=mean(turn)
//
// twoway rarea min95 max95 mean_turn if toplot, color(dkorange*.1) || ///
// 	line estimate average_marginal_value mean_turn if toplot, ///
// 	sort yline(0, lcolor(gs8) lpattern(dot)) ///
// 	legend(order(2 3) label(2 "Marginal Change in Win Prob") label(3 "Marginal Value of Time"))
// graph rename heterogeneity_by_turn, replace
// graph export "heterogeneity_by_turn`1'_`2'.pdf", as(pdf) replace
